package com.mars.base.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.mars.base.common.exception.BizException;
import com.mars.base.common.utils.CommonUtils;
import com.mars.base.common.utils.page.PageParam;
import com.mars.base.common.utils.web.WebUtil;

/**
 * Spring MVC 基础控制类
 * 
 * @author 杨浩泉
 * @version 2016年10月14日
 */
public class BaseController extends SupperController {
	
	/**
	 * 获取分页参数，包含当前页、每页记录数.
	 * @return
	 */
	public PageParam getPageParam() {
		return new PageParam(getPageNum(), getNumPerPage(), getOrderBy(), getSortName(), getSortOrder()) ;
	}
	public PageParam getPageParam(Integer page, Integer rows) {
		return new PageParam(getPageNum(page), getNumPerPage(rows), getOrderBy(), getSortName(), getSortOrder()) ;
	}
	public PageParam getPageParam(Integer page, Integer rows, String sort, String order) {
		return new PageParam(getPageNum(page), getNumPerPage(rows), getOrderBy(sort, order), getSortName(sort), getSortOrder(order)) ;
	}

	/**
	 * 起始页
	 * @param page 通过URL传入起始页
	 * @return
	 */
	private int getPageNum(Integer page) {
		String pageNumStr = request.getParameter("page");
		int pageNum = 1;
		//指定起始页
		if(null != page) {
			pageNum = page ;
		}
		if (StringUtils.isNotBlank(pageNumStr)) {
			pageNum = Integer.valueOf(pageNumStr);
		}
		return pageNum;
	}
	private int getPageNum() {
		return getPageNum(null) ;
	}
	
	/**
	 * 获取每页记录数
	 * 如果没有值则默认返回20.
	 * @param rows 通过URL传入每页显示的记录数
	 * @return
	 */
	private int getNumPerPage(Integer rows) {
		String numPerPageStr = request.getParameter("rows");
		int numPerPage = 20;
		//通过URL指定每页显示多少条记录
		if(null != rows) {
			numPerPage = rows ;
		}
		if (StringUtils.isNotBlank(numPerPageStr)) {
			numPerPage = Integer.parseInt(numPerPageStr);
		}
		return numPerPage;
	}
	private int getNumPerPage() {
		return getNumPerPage(null) ;
	}

	/**
	 * 查询排序
	 * @param _sortName 通过URL传入排序的类型
	 * @param _sortOrder 通过URL传入排序的字段
	 * @return
	 */
	private String getOrderBy(String _sortName, String _sortOrder) {
		String sortName = getSortName(_sortName);
		String sortOrder = getSortOrder(_sortOrder);
		//指定SortName
		if(null != _sortName) {
			sortName = _sortName ;
		}
		//指定sortOrder
		if(null != _sortOrder) {
			sortOrder = _sortOrder ;
		}
		if (CommonUtils.isNotEmpty(sortName)) {
			return sortName + " " + (CommonUtils.isNotEmpty(sortName) ? sortOrder : "DESC") ;
		}
		return null ;
	}
	private String getOrderBy() {
		return getOrderBy(null, null) ; 
	}
	
	private String getSortName(String _sortName) {
		String sortName = request.getParameter("sortName");
		//指定SortName
		if(null != _sortName) {
			sortName = _sortName ;
		}
		if (null == sortName || CommonUtils.isEmpty(sortName)) {
			return null ;
		}
		return CommonUtils.upperCharToUnderLine(sortName) ;
	}
	private String getSortName() {
		return getSortName(null) ; 
	}
	
	private String getSortOrder(String _sortOrder) {
		String sortOrder = request.getParameter("sortOrder");
		//指定SortName
		if(null != _sortOrder) {
			sortOrder = _sortOrder ;
		}
		if (CommonUtils.isNotEmpty(sortOrder)) {
			return CommonUtils.isEmpty(sortOrder) ? "DESC" : sortOrder ;
		}
		return null ;
	}
	private String getSortOrder() {
		return getSortOrder(null) ; 
	}
	
	
	/**
	 * 统一异常处理
	 */
	@ExceptionHandler(Exception.class)
	public ModelAndView handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
		
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			//设置跨域请求
			response.setHeader("Access-Control-Allow-Origin", "*");
			response.setHeader("Access-Control-Allow-Methods", "*");
			response.setHeader("Access-Control-Max-Age", "3628800");
			response.setContentType("application/json;charset=utf-8");
			
			PrintWriter out = null;
			try {
				out = response.getWriter();
				if (e instanceof BizException) {
					response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
					map.put("status", response.getStatus());
					map.put("message", e.getMessage());
					map.put("request", WebUtil.getCurrentUrl(request, true));
					out.print(JSON.toJSONString(map));
				} else if(e instanceof com.alibaba.dubbo.rpc.RpcException) {
					response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
					map.put("status", response.getStatus());
					map.put("message", "服务不可用，或已下架，请联系管理员。");
					map.put("request", WebUtil.getCurrentUrl(request, true));
					out.print(JSON.toJSONString(map));
				} else if(e instanceof NullPointerException) {
					response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
					map.put("status", response.getStatus());
					map.put("message", "空指针异常");
					map.put("request", WebUtil.getCurrentUrl(request, true));
					out.print(JSON.toJSONString(map));
				} else {
					response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
					map.put("status", response.getStatus());
					map.put("message", e.getMessage());
					map.put("request", WebUtil.getCurrentUrl(request, true));
					out.print(JSON.toJSONString(map));
				}

			} catch (IOException ioEx) {
				ioEx.printStackTrace();
			} finally {
				out.flush();
				out.close();
			}
			return null;
		} finally {
			logger.error("Web异常拦截："+map.get("message"), e);
		}
	}
}
